from datetime import datetime, timedelta

from werkzeug.security import generate_password_hash, check_password_hash

from config import Config
from logger_config import get_logger
from extensions import db
from models import User, QueryRecord
from utils.token_utils import generate_token
from auth import validate_user_input

logger = get_logger(__name__)


class UserService:
    """用户服务类，负责用户管理相关功能"""

    def __init__(self):
        self.config = Config()

    def create_user(self, username, email, password, role='user'):
        """创建新用户
        
        Args:
            username: 用户名
            email: 邮箱
            password: 密码
            role: 角色，默认为'user'
        
        Returns:
            dict: 创建结果
        """
        try:
            # 检查用户名是否已存在
            if User.query.filter_by(username=username).first():
                return {
                    'success': False,
                    'error': '用户名已存在',
                    'error_code': 'USERNAME_EXISTS'
                }

            # 检查邮箱是否已存在
            if User.query.filter_by(email=email).first():
                return {
                    'success': False,
                    'error': '邮箱已被注册',
                    'error_code': 'EMAIL_EXISTS'
                }

            # 验证用户输入（包括密码强度）
            validation_errors = validate_user_input(username=username, email=email, password=password)
            if validation_errors:
                return {
                    'success': False,
                    'error': '输入验证失败',
                    'errors': validation_errors,
                    'error_code': 'VALIDATION_ERROR'
                }

            # 创建用户
            user = User(
                username=username,
                email=email,
                password_hash=generate_password_hash(password),
                role=role,
                created_at=datetime.utcnow(),
                is_active=True
            )

            db.session.add(user)
            db.session.commit()

            logger.info(f"用户创建成功: {username} ({email})")

            return {
                'success': True,
                'user_id': user.id,
                'message': '用户创建成功'
            }

        except Exception as e:
            logger.error(f"创建用户失败: {str(e)}")
            try:
                db.session.rollback()
            except:
                pass
            return {
                'success': False,
                'error': f'创建用户失败: {str(e)}',
                'error_code': 'USER_CREATION_ERROR'
            }

    def authenticate_user(self, username, password):
        """用户认证
        
        Args:
            username: 用户名或邮箱
            password: 密码
        
        Returns:
            dict: 认证结果
        """
        try:
            # 查找用户（支持用户名或邮箱登录）
            user = User.query.filter(
                (User.username == username) | (User.email == username)
            ).first()

            if not user:
                return {
                    'success': False,
                    'error': '用户不存在',
                    'error_code': 'USER_NOT_FOUND'
                }

            # 检查用户是否激活
            if not user.is_active:
                return {
                    'success': False,
                    'error': '用户账户已被禁用',
                    'error_code': 'USER_DISABLED'
                }

            # 验证密码
            if not check_password_hash(user.password_hash, password):
                # 记录登录失败
                self._record_login_attempt(user.id, False)
                return {
                    'success': False,
                    'error': '密码错误',
                    'error_code': 'INVALID_PASSWORD'
                }

            # 更新最后登录时间
            user.last_login = datetime.utcnow()
            db.session.commit()

            # 记录登录成功
            self._record_login_attempt(user.id, True)

            # 生成JWT token
            token = generate_token({
                'user_id': user.id,
                'username': user.username,
                'role': user.role
            })

            logger.info(f"用户登录成功: {user.username}")

            return {
                'success': True,
                'user': {
                    'id': user.id,
                    'username': user.username,
                    'email': user.email,
                    'role': user.role,
                    'created_at': user.created_at.isoformat() if user.created_at else None,
                    'last_login': user.last_login.isoformat() if user.last_login else None
                },
                'token': token
            }

        except Exception as e:
            logger.error(f"用户认证失败: {str(e)}")
            return {
                'success': False,
                'error': f'认证失败: {str(e)}',
                'error_code': 'AUTHENTICATION_ERROR'
            }

    def get_user_by_id(self, user_id):
        """根据ID获取用户信息
        
        Args:
            user_id: 用户ID
        
        Returns:
            dict: 用户信息，如果不存在返回None
        """
        try:
            user = User.query.get(user_id)
            if not user:
                return None

            return {
                'id': user.id,
                'username': user.username,
                'email': user.email,
                'role': user.role,
                'is_active': user.is_active,
                'created_at': user.created_at.isoformat() if user.created_at else None,
                'last_login': user.last_login.isoformat() if user.last_login else None,
                'total_queries': user.total_queries,
                'total_cost': user.total_cost,
                'total_tokens': user.total_tokens
            }

        except Exception as e:
            logger.error(f"获取用户信息失败: {str(e)}")
            return None

    def get_user_by_username(self, username):
        """根据用户名获取用户信息
        
        Args:
            username: 用户名
        
        Returns:
            dict: 用户信息，如果不存在返回None
        """
        try:
            user = User.query.filter_by(username=username).first()
            if not user:
                return None

            return self.get_user_by_id(user.id)

        except Exception as e:
            logger.error(f"获取用户信息失败: {str(e)}")
            return None

    def update_user_profile(self, user_id, **kwargs):
        """更新用户资料
        
        Args:
            user_id: 用户ID
            **kwargs: 要更新的字段
        
        Returns:
            dict: 更新结果
        """
        try:
            user = User.query.get(user_id)
            if not user:
                return {
                    'success': False,
                    'error': '用户不存在',
                    'error_code': 'USER_NOT_FOUND'
                }

            # 允许更新的字段
            allowed_fields = ['email', 'is_active']

            for field, value in kwargs.items():
                if field in allowed_fields and hasattr(user, field):
                    setattr(user, field, value)

            db.session.commit()
            
            logger.info(f"用户资料更新成功: {user.username}")

            return {
                'success': True,
                'message': '用户资料更新成功'
            }

        except Exception as e:
            logger.error(f"更新用户资料失败: {str(e)}")
            try:
                db.session.rollback()
            except:
                pass
            return {
                'success': False,
                'error': f'更新失败: {str(e)}',
                'error_code': 'UPDATE_ERROR'
            }

    def change_password(self, user_id, old_password, new_password):
        """修改密码
        
        Args:
            user_id: 用户ID
            old_password: 旧密码
            new_password: 新密码
        
        Returns:
            dict: 修改结果
        """
        try:
            user = User.query.get(user_id)
            if not user:
                return {
                    'success': False,
                    'error': '用户不存在',
                    'error_code': 'USER_NOT_FOUND'
                }

            # 验证旧密码
            if not check_password_hash(user.password_hash, old_password):
                return {
                    'success': False,
                    'error': '原密码错误',
                    'error_code': 'INVALID_OLD_PASSWORD'
                }

            # 验证新密码强度
            if not self._validate_password(new_password):
                return {
                    'success': False,
                    'error': '新密码强度不足，至少需要8位字符，包含字母和数字',
                    'error_code': 'WEAK_PASSWORD'
                }

            # 更新密码
            user.password_hash = generate_password_hash(new_password)
            db.session.commit()
            
            logger.info(f"用户密码修改成功: {user.username}")

            return {
                'success': True,
                'message': '密码修改成功'
            }

        except Exception as e:
            logger.error(f"修改密码失败: {str(e)}")
            try:
                db.session.rollback()
            except:
                pass
            return {
                'success': False,
                'error': f'修改密码失败: {str(e)}',
                'error_code': 'PASSWORD_CHANGE_ERROR'
            }

    def get_all_users(self, page=1, per_page=20):
        """获取所有用户（分页）
        
        Args:
            page: 页码
            per_page: 每页数量
        
        Returns:
            dict: 用户列表和分页信息
        """
        try:
            pagination = User.query.paginate(
                page=page, per_page=per_page, error_out=False
            )

            users = [{
                'id': user.id,
                'username': user.username,
                'email': user.email,
                'role': user.role,
                'is_active': user.is_active,
                'created_at': user.created_at.isoformat() if user.created_at else None,
                'last_login': user.last_login.isoformat() if user.last_login else None,
                'total_queries': user.total_queries,
                'total_cost': user.total_cost,
                'total_tokens': user.total_tokens
            } for user in pagination.items]

            return {
                'users': users,
                'pagination': {
                    'page': pagination.page,
                    'pages': pagination.pages,
                    'per_page': pagination.per_page,
                    'total': pagination.total,
                    'has_next': pagination.has_next,
                    'has_prev': pagination.has_prev
                }
            }

        except Exception as e:
            logger.error(f"获取用户列表失败: {str(e)}")
            return {
                'users': [],
                'pagination': {
                    'page': 1,
                    'pages': 0,
                    'per_page': per_page,
                    'total': 0,
                    'has_next': False,
                    'has_prev': False
                }
            }

    def delete_user(self, user_id):
        """删除用户
        
        Args:
            user_id: 用户ID
        
        Returns:
            dict: 删除结果
        """
        try:
            user = User.query.get(user_id)
            if not user:
                return {
                    'success': False,
                    'error': '用户不存在',
                    'error_code': 'USER_NOT_FOUND'
                }

            # 检查是否为管理员（防止删除管理员）
            if user.role == 'admin':
                return {
                    'success': False,
                    'error': '不能删除管理员用户',
                    'error_code': 'CANNOT_DELETE_ADMIN'
                }

            # 删除用户相关的查询记录和用户
            db.session.query(QueryRecord).filter_by(user_id=user_id).delete()
            db.session.delete(user)
            db.session.commit()
            
            logger.info(f"用户删除成功: {user.username}")

            return {
                'success': True,
                'message': '用户删除成功'
            }

        except Exception as e:
            logger.error(f"删除用户失败: {str(e)}")
            try:
                db.session.rollback()
            except:
                pass
            return {
                'success': False,
                'error': f'删除用户失败: {str(e)}',
                'error_code': 'USER_DELETION_ERROR'
            }

    # 密码验证现在统一使用 auth.py 中的 validate_user_input 函数

    def _record_login_attempt(self, user_id, success):
        """记录登录尝试（预留功能）
        
        Args:
            user_id: 用户ID
            success: 是否成功
        """
        # 这里可以实现登录尝试记录功能
        # 用于安全监控和防暴力破解
        pass

    def get_user_statistics(self):
        """获取用户统计信息
        
        Returns:
            dict: 统计信息
        """
        try:
            total_users = User.query.count()
            active_users = User.query.filter_by(is_active=True).count()
            admin_users = User.query.filter_by(role='admin').count()

            # 最近7天注册的用户
            week_ago = datetime.utcnow() - timedelta(days=7)
            recent_users = User.query.filter(User.created_at >= week_ago).count()

            return {
                'total_users': total_users,
                'active_users': active_users,
                'inactive_users': total_users - active_users,
                'admin_users': admin_users,
                'recent_users': recent_users
            }

        except Exception as e:
            logger.error(f"获取用户统计失败: {str(e)}")
            return {
                'total_users': 0,
                'active_users': 0,
                'inactive_users': 0,
                'admin_users': 0,
                'recent_users': 0
            }


# 全局用户服务实例
user_service = UserService()
